package xp.ass.imitate.yml;

import lombok.Data;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.Resource;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.reader.UnicodeReader;
import org.yaml.snakeyaml.representer.Representer;

import java.io.Reader;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author chent3
 * @date 2024/7/17
 */
@Data
public class YmlProcessor {

    private final Log logger = LogFactory.getLog(getClass());

    public List<Resource> resource;


    public Map<String, Object> process() {
        Yaml yaml = createYaml();

        Map<String, Object> result = new LinkedHashMap<>();

        for (Resource resource : resource) {
            doProcess(yaml, resource);
        }

        return result;
    }

    private static Yaml createYaml() {
        LoaderOptions loaderOptions = new LoaderOptions();
        loaderOptions.setAllowDuplicateKeys(false);
        Yaml yaml = new Yaml(new FilteringConstructor(loaderOptions), new Representer(),
                new DumperOptions(), loaderOptions);
        return yaml;
    }

    private void doProcess(Yaml yaml, Resource resource) {
        try (Reader reader = new UnicodeReader(resource.getInputStream())) {
            try {
                for (Object object : yaml.loadAll(reader)) {

                }
            } catch (Exception ex) {
                logger.error("yml parse error：" + ExceptionUtils.getStackTrace(ex));
            }

        } catch (Exception ex) {
            throw new RuntimeException("yml parse error：" + ExceptionUtils.getStackTrace(ex));
        }

    }

    public Map<String, Object> asMap(Object object) {
        Map<String, Object> result = new LinkedHashMap<>();
        if (object instanceof Map<?, ?>) {
            ((Map<?, ?>) object).forEach((k, v) -> {

                result.put(
                        (k instanceof CharSequence) ? ((CharSequence) k).toString() :
                                // map 类型的
                                String.format("[%s]", k.toString())
                        , v instanceof Map ? asMap(v) : v);
            });
        } else {
            result.put("document", object);
        }
        return result;
    }


    protected static class FilteringConstructor extends Constructor {
        FilteringConstructor(LoaderOptions loaderOptions) {
            super(loaderOptions);
        }
    }
}
